﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Settings;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell.Settings;
using centraldba_library.Data;
using centraldba_library.Admin;
using centraldba.msx_config_addin.Events;
using centraldba.msx_config_addin.Forms;

namespace centraldba.msx_config_addin
{
    /// <summary>
    /// Interaction logic for msx_list.xaml
    /// </summary>
    public partial class msx_list : UserControl
    {
        #region " Fields "

        protected ObservableCollection<msx_server> _servers;
        private ToolWindowPane _parent;
        private const string CollectionName = "MSXConfig";
        private const string PropertyName = "MSXServer";
        private const string connectionStringTemplate = "Data Source=yourserver;Initial Catalog=centraldba_db;Integrated Security=True";

        #endregion

        #region " Constructor "

        public msx_list(ToolWindowPane parentWindow)
        {
            InitializeComponent();

            // Initialize private fields
            _servers = new ObservableCollection<msx_server>();
            _parent = parentWindow;

            this.Loaded += new RoutedEventHandler(msx_list_Loaded);
        }

        void msx_list_Loaded(object sender, RoutedEventArgs e)
        {
            // Read Existing Server Definitions
            ReadStoredSettings();

            // Data bind to the tree view
            this.tvMSXServers.DataContext = _servers;
        }

        #endregion

        #region " Events "

        public event EventHandler<SelectedServerEventArgs<msx_server>> MSXServerSelected;
        public event EventHandler MSXServerUnselected;

        #endregion

        #region " Methods "

        #region " Reading the Settings Collection "

        private void ReadStoredSettings()
        {
            // Open up the Settings Manager
            SettingsManager theManager = new ShellSettingsManager(_parent);
            WritableSettingsStore theStore = theManager.GetWritableSettingsStore(SettingsScope.UserSettings);

            // Does the Settings Collection Exist yet?
            if (theStore.CollectionExists(CollectionName))
            {
                foreach (string s in theStore.GetPropertyNames(CollectionName))
                {
                    string[] values = theStore.GetString(CollectionName, s).Split('|');
                    if (!values[0].ToString().Trim().Equals(string.Empty) && !values[1].ToString().Trim().Equals(string.Empty))
                    {
                        msx_server defServer = new msx_server(connectionStringTemplate, values[0].ToString().Trim(), values[1].ToString().Trim());
                        if (!_servers.Contains(defServer))
                            _servers.Add(defServer);
                    }
                }
            }


            // Cleanup References
            theStore = null;
            theManager = null;
        }
        private Int32 GetNextMSXServerNumber(WritableSettingsStore theStore)
        {
            // Declare Local Variables
            Int32 iCounter = 0;

            // Does the Settings Collection Exist yet?
            if (theStore.CollectionExists(CollectionName))
            { 
                // Loop through the Settings Collection to get the first available PropertyName
                while (theStore.PropertyExists(CollectionName, PropertyName + iCounter.ToString()))
                {
                    iCounter++;
                }
            }

            // Return the Counter Value
            return iCounter;
        }
        private string GetExistingProperty(WritableSettingsStore theStore, string propertyValue)
        {
            // Declare Local Variables
            Int32 iCounter = 0;
            bool isPropertyFound = false;

            // Does the Settings Collection Exist yet?
            if (theStore.CollectionExists(CollectionName))
            {
                // Loop through the Settings Collection to get the first available PropertyName
                while (theStore.PropertyExists(CollectionName, PropertyName + iCounter.ToString()))
                {
                    if (theStore.GetString(CollectionName, PropertyName + iCounter.ToString()).Equals(propertyValue))
                    {
                        isPropertyFound = true;
                        break;
                    }

                    iCounter++;
                }
            }

            // Return the current property name
            if (isPropertyFound)
                return PropertyName + iCounter.ToString();
            else
                return string.Empty;
        }

        #endregion

        public void add_msx_server()
        {
            IVsUIShell uiShell = (IVsUIShell)Package.GetGlobalService(typeof(SVsUIShell));

            //get the owner of this dialog
            IntPtr hwnd;
            uiShell.GetDialogOwnerHwnd(out hwnd);

            // Create the Child Dialog
            connect_database cd = new connect_database(connectionStringTemplate);
            cd.MSXServerSelected += new EventHandler<SelectedServerEventArgs<msx_server>>(cd_MSXServerSelected);
            cd.WindowStartupLocation = WindowStartupLocation.CenterOwner;

            // Display the Modal Window
            uiShell.EnableModeless(0);
            try
            {
                Microsoft.Internal.VisualStudio.PlatformUI.WindowHelper.ShowModal(cd);
            }
            finally
            {
                uiShell.EnableModeless(1);
                uiShell = null;
                cd = null;
            }
        }

        void cd_MSXServerSelected(object sender, SelectedServerEventArgs<msx_server> e)
        {
            add_msx_server(e.Value.server_name, e.Value.database_name);
        }

        public void add_msx_server(string serverName, string databaseName)
        {
            // Declare Local Variables
            string newPropertyName = string.Empty;
            msx_server newServer;

            // Open up the Settings Manager
            SettingsManager theManager = new ShellSettingsManager(_parent);
            WritableSettingsStore theStore = theManager.GetWritableSettingsStore(SettingsScope.UserSettings);

            // Ensure the Settings Collection has been added
            if (!theStore.CollectionExists(CollectionName))
                theStore.CreateCollection(CollectionName);

            // Add the server to the Collection (if not already there - no duplicates allowed)
            if (GetExistingProperty(theStore, serverName + "|" + databaseName).Equals(string.Empty))
            { 
                newPropertyName = PropertyName + GetNextMSXServerNumber(theStore).ToString();
                if (!theStore.PropertyExists(CollectionName, newPropertyName))
                {
                    theStore.SetString(CollectionName, newPropertyName, serverName + "|" + databaseName);

                    // Add the server to the UI
                    newServer = new msx_server(connectionStringTemplate, serverName, databaseName);
                    if (!_servers.Contains(newServer))
                        _servers.Add(newServer);
                }
            }

            // Cleanup References
            newServer = null;
            theStore = null;
            theManager = null;
        }

        public void delete_msx_server()
        {
            // Declare Local Variables
            string currentPropertyName;
            centraldba_library.Admin.msx_server theServer = (centraldba_library.Admin.msx_server)tvMSXServers.SelectedItem;

            // Open up the Settings Manager
            SettingsManager theManager = new ShellSettingsManager(_parent);
            WritableSettingsStore theStore = theManager.GetWritableSettingsStore(SettingsScope.UserSettings);

            // Remove the server from the Settings Collection
            currentPropertyName = GetExistingProperty(theStore, theServer.server_name + "|" + theServer.database_name);
            theStore.DeleteProperty(CollectionName, currentPropertyName);

            // Remove the server from the UI
            _servers.Remove(theServer);

            // Cleanup References
            theServer = null;
            theStore = null;
            theManager = null;
        }

        public void refresh_msx_server()
        {
            _servers.Clear();
            ReadStoredSettings();
        }

        private void tvMSXServers_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (tvMSXServers.SelectedItem is msx_server)
                MSXServerSelected(this, new SelectedServerEventArgs<msx_server>((msx_server)tvMSXServers.SelectedItem));
            else
                MSXServerUnselected(this, new EventArgs());
        }

        #endregion
    }
}